from toutiao import db
from flask import current_app
from flask import g
from flask import request
from flask_restful.inputs import regex
from flask_restful import reqparse
from flask_restful import Resource

from models.user import User
from toutiao.utils.parsers import check_mobile
from toutiao.utils.token import get_user_token


class LoginResource(Resource):

    def get(self):

        return {'view':'login'}

    def post(self):
        """
        接收数据
        验证数据
        根据手机号进行数据库的查新, 如果不存在则保存数据
        生成token
        返回相应
        """
        # 接收数据
        data = request.json
        # 验证数据
        parser = reqparse.RequestParser()
        parser.add_argument('mobile', type=check_mobile, location='json', required=True, )
        parser.add_argument('code', type=regex(r'\d{6}'), location='json', required=True)
        args = parser.parse_args()
        mobile = args.get('mobile')
        sms_code = args.get('code')

        # 验证短信码省略
        # 从redis中获取验证码
        key = 'app:code:{}'.format(mobile)
        redis_code = current_app.redis_store.get(key)

        if not redis_code or redis_code.decode() != sms_code:
            return {'message': 'Invalid code.'}, 400

        # 3.根据手机号进行数据库查询，如果不存在则保存数据
        user = None
        try:
            user = User.query.filter_by(mobile=args.get('mobile')).first()
        except Exception as e:
            current_app.logger.error(e)

        if user is None:
            user_id = current_app.id_worker.get_id()
            user = User()
            user.id = user_id
            user.mobile = args.get('mobile')
            user.name = args.get('mobile')
            db.session.add(user)
            db.session.commit()
        else:
            from datetime import datetime
            user.last_login = datetime.now()
            db.session.commit()

        # 缓存用户的信息到redis
        # user:{user_id}: profile: string
        # save(user_id)
        # 使用刚定义的方法将数据保存到缓存中
        from cache.user import UserProfileCache, UserStatusCache
        UserProfileCache(user.id).save()
        # 缓存用户的状态
        UserStatusCache(user.id).save(user.status)

        # 4.生成token
        from toutiao.utils.token import get_user_token
        token, refresh_token = get_user_token(user.id)

        # 5.返回相应
        return {'token': token, 'refresh_token':refresh_token}

    def put(self):
        # 只有user_id和refresh都正确才行
        if g.user_id and g.is_refresh_token:
            from cache.user import UserStatusCache

            if not UserStatusCache(g.user_id).get():
                return {'message': 'login'}, 403

            # 正确就重写生成一个token
            from toutiao.utils.token import get_user_token
            token, refresh_token = get_user_token(g.user_id)

            return {'token': token}

        else:
            # user_id 和 refresh有一个不正确逗返回403让前端登陆
            return {'message':'login'}, 403



#查询数据
from toutiao.utils.decorators import loginrequired
class UserInfoResource(Resource):

    method_decorators = [loginrequired]

    def get(self):
        """
        1.用户信息的获取,直接调用缓存类

        :return:
        """
        # user = User.query.filter_by(id=1).first()
        #
        # user_data = {
        #     'id': user.id,
        #     'mobile': user.mobile,
        #     'name': user.name,
        #     'photo': user.profile_photo or '',
        #     'is_media': user.is_media,
        #     'intro': user.introduction or '',
        #     'certi': user.certificate or '',
        # }
        # user_id 先写死
        user_id = g.user_id
        from cache.user import UserProfileCache
        user_data = UserProfileCache(user_id).get()

        return user_data



class SmsCodeResource(Resource):

    def get(self, mobile):
        # 获取手机号码
        # 生成短信验证码
        from random import choice
        from string import digits   # 数字0-9

        code = ''.join([choice(digits) for _ in range(6)])

        # 保存验证码
        current_app.redis_store.setex('app:code:{}'.format(mobile))

        current_app.logger.info(code)

        # 返回响应
        return {
            "mobile": mobile
        }

